package DropPool

import (
	"math/rand"
	"sanguo/node/common/com_type"
	"sanguo/node/node_game"
	table_DropPool "sanguo/node/table/excel/table/DropPool"
	cs_msg "sanguo/protocol/cs/message"

	"github.com/golang/protobuf/proto"
)

type AwardInfo struct {
	Type  int32
	ID    int32
	Count int32
}

type Award struct {
	Infos map[int32]*AwardInfo // key 为 ID*100 + Type
}

func (this *Award) AddInfo(dropType, dropID, count int32) {
	info := &AwardInfo{
		Type:  dropType,
		Count: count,
	}

	if dropType == com_type.Drop_Exp || dropType == com_type.Drop_Gold || dropType == com_type.Drop_Moon {
		info.ID = 0
	} else {
		info.ID = dropID
	}
	id := info.ID*100 + dropType
	this.Infos[id] = info
}

func IsDrop(drop *table_DropPool.Drops_) bool {
	return true
}

//随机掉落
func RandDrop(dropCount, wave, chance int32) (int32, bool) {
	//rand.Seed(time.Now().Unix())
	isDrop := rand.Int31n(10000) + 1 //1-10000随机

	if isDrop > chance {
		return 0, false
	}

	var waveCount int32 = 0
	if wave != 0 {
		waveCount = rand.Int31n(wave*2) - wave
	}
	count := dropCount + waveCount
	if count <= 0 {
		count = 1
	}

	return count, true
}

//累加掉落
func FixedDrop() {

}

//等概率掉落
func EqualDrop() {

}

//池中池的处理
func (this *Award) DropPool_Pool(DropPoolID, count int32) {
	for i := int32(0); i < count; i++ {
		poolAward := InitAward(DropPoolID)
		for id, info := range poolAward.Infos {
			info_ := this.Infos[id]
			if info_ != nil {
				info_.Count += info.Count
			} else {
				this.Infos[id] = info
			}
		}
	}
}

//所有道具都随机一次 种类在最大与最小值之间
func (this *Award) DropPoolRand(DropPoolID int32) {
	drop := table_DropPool.Table_.IDMap[DropPoolID]
	//掉落数量限制
	dropCountLimit := false

	dropMaxCount := drop.MaxCount
	dropMinCount := drop.MinCount

	if dropMaxCount != 0 {
		dropCountLimit = true
		if dropMinCount > dropMaxCount {
			return
		}
	}
	var dropCount int32 = 0 //掉落数计数

	for dropCount < dropMinCount {
		for _, v := range drop.Drops {
			if dropCountLimit && dropCount >= dropMaxCount {
				break
			}
			if v.DropType != 0 { //判断缺省
				if v.DropType == com_type.Drop_Pool {
					if count, b := RandDrop(v.Count, v.Wave, v.Chance); b {
						dropCount += 1
						this.DropPool_Pool(v.DropID, count)
					}
				} else {
					if count, b := RandDrop(v.Count, v.Wave, v.Chance); b {
						dropCount += 1
						this.AddInfo(v.DropType, v.DropID, count)
					}
				}
			}
		}
	}
}

//固定掉落 有啥掉啥
func (this Award) DropPoolFixed(DropPoolID int32) {
	drop := table_DropPool.Table_.IDMap[DropPoolID]
	for _, v := range drop.Drops {
		if v.DropType != 0 { //判断缺省
			if v.DropType == com_type.Drop_Pool {
				count, _ := RandDrop(v.Count, v.Wave, int32(10001))
				this.DropPool_Pool(v.DropID, count)

			} else {
				count, _ := RandDrop(v.Count, v.Wave, int32(10001))
				this.AddInfo(v.DropType, v.DropID, count)
			}
		}
	}
}

//100%概率下掉落一个
func (this *Award) DropPoolEqual(DropPoolID int32) {
	drop := table_DropPool.Table_.IDMap[DropPoolID]
	//掉落数量限制
	dropMinCount := int32(1)
	var dropCount int32 = 0 //掉落数计数

	for dropCount < dropMinCount {
		isDrop := rand.Int31n(10000) + 1 //1-10000随机
		var pp_ int32 = 0                //读表的概率累加值
		for _, v := range drop.Drops {
			if v.DropType != 0 { //判断缺省
				pp_ += v.Chance
				if isDrop <= pp_ {
					if v.DropType == com_type.Drop_Pool {
						dropCount += 1
						count, _ := RandDrop(v.Count, v.Wave, int32(10001))
						this.DropPool_Pool(v.DropID, count)

					} else {
						dropCount += 1
						count, _ := RandDrop(v.Count, v.Wave, int32(10001))
						this.AddInfo(v.DropType, v.DropID, count)
					}
					break
				}
			}
		}
	}
}

//奖励计算
func InitAward(DropPoolID int32) *Award {
	//读表
	dropDef := table_DropPool.Table_.IDMap[DropPoolID]
	if dropDef == nil {
		return nil
	}
	award := &Award{
		Infos: map[int32]*AwardInfo{},
	}

	//判读掉落池类型
	switch dropDef.Type {
	case com_type.DropPool_Rand: //所有道具随机
		award.DropPoolRand(DropPoolID)

	case com_type.DropPool_Fixed: //固定掉落
		award.DropPoolFixed(DropPoolID)

	case com_type.DropPool_Equal: //所有道具瓜分100%掉落1个
		award.DropPoolEqual(DropPoolID)
	default:
		node_game.Infoln("DropPool Type is fail")
	}

	return award
}

//打包Award
func PackAward(award *Award) *cs_msg.Award {
	if award == nil {
		return nil
	}
	toC := &cs_msg.Award{}
	for _, v := range award.Infos {
		info := &cs_msg.AwardInfo{
			AwardType: proto.Int32(v.Type),
			ID:        proto.Int32(v.ID),
			Count:     proto.Int32(v.Count),
		}
		toC.AwardInfos = append(toC.AwardInfos, info)
	}
	return toC
}

//多个奖励合并为一个奖励
func PackAwardsToOne(awards []*Award) *Award {
	award := &Award{
		Infos: map[int32]*AwardInfo{},
	}
	for _, a := range awards {
		if a != nil {
			for id, info := range a.Infos {
				info_ := award.Infos[id]
				if info_ != nil {
					info_.Count += info.Count
				} else {
					award.Infos[id] = info
				}
			}
		}
	}
	return award
}

//根据需要获取奖励中的某一种奖励
func GetTypeAward(typeID int32, award *Award) map[int32]int32 {
	ret := map[int32]int32{}
	if award != nil {
		for _, v := range award.Infos {
			if v.Type == typeID {
				ret[v.ID] = v.Count
			}
		}
	}
	return ret
}
